// -*-mode:c++; coding:utf-8-*-

#ifndef _XBASE_SERVICE_PROVIDER_HPP_
#define _XBASE_SERVICE_PROVIDER_HPP_

#include <protocol.hpp>
#include <protocol_packet.hpp>

#include "service.hpp"
#include "table_schema.hpp"
#include "kv_scan_context.hpp"
#include "naming_strategy.hpp"
#include "tablet.hpp"

namespace xbase
{
	// interface with server and service
	//
	// 该接口将服务器的架构与提供的服务分离开来，使得每一个部分可以单独进行优化。
	//
	// 接口的输入参数是服务器部分的定义的结构，转换为内部结构后调用下层的服务组件。
	//
	// 所有接口的返回类型为int，值为0是正常，非0为出错。
	class service_provider
	{
	public:
		//typedef boost::shared_ptr<service_provider> pointer;

	public:
		
		void do_load_tablet(request::pointer request_ptr,
				    response::pointer response_ptr);
		
		void do_remove_tablet(request::pointer request_ptr,
				      response::pointer response_ptr);
		
		void do_root_meta(request::pointer request_ptr);
		
		void do_table_info(request::pointer request_ptr);
		
		void do_restart(request::pointer request_ptr);
		
		void do_unexpected(request::pointer request_ptr);
		
		void do_read(request::pointer request_ptr,
			     response::pointer response_ptr);
		
		void do_write(request::pointer request_ptr,
			      response::pointer response_ptr);
		
		void do_batch_write(request::pointer request_ptr,
				    response::pointer response_ptr);
		
		void do_scan_open(request::pointer request_ptr,
				  response::pointer response_ptr);
		
		
		void do_scan_next(request::pointer request_ptr,
				  response::pointer response_ptr);
		
		void do_scan_close(request::pointer request_ptr,
				   response::pointer response_ptr);
		
		void do_list_tablet(request::pointer request_ptr,
				    response::pointer response_ptr);
		
		void construct_heartbeat(response::pointer message);
		void construct_report(response::pointer report);
		
	public:
		// 
		// interface
		//
		
		int update_table_schema(const TableInfo &p_info);

		int load_tablet(const LoadTabletReq &req,
				LoadTabletResp &p_resp,
				TabletSplitReport &p_split_report);
		int unload_tablet(const RemoveTabletReq &req, RemoveTabletResp &p_resp);
		int unload_tablet(const tablet::pointer &tablet, const std::string &log_message);

		int scan_open(ScanOpenReq &req, ScanOpenResp &resp);
		int scan_next(const ScanNextReq &req, ScanNextResp &resp);
		int scan_close(const ScanCloseReq &req, ScanCloseResp &resp);

		int write(request::pointer request_ptr,
			  protocol::write_response_v2 &resp);
		int batch_write(request::pointer request_ptr,
				protocol::batch_write_response_v2 &resp);
		int read(const ReadReq &req, ReadResp &resp);

		int query_root_meta_address();

		int update_split_tablet_info(const tablet::pointer &tablet,
					     TabletSplitReport &p_split_report);

		void report_tablet_server_quit();

		int list_tablet(std::vector<TabletInfo> &tablet_infos);

		int unload_all_tablet(const std::string &log_message);

		
	protected:
		inline
		table_schema::pointer create_schema(const table_info &p_info)
			{
				// DONE: 通过table_info创建一个schema
				return table_schema::pointer(new table_schema(p_info));
			}

		inline
		kv_scan_context::pointer create_context(const ScanOpenReq &p_req)
			{
				// 通过scan_open_req创建一个scan_context
				return kv_scan_context::pointer(new kv_scan_context(p_req.tablet_name,
										    p_req.start_row_name,
										    p_req.end_row_name,
										    p_req.column_names,
										    p_req.latest_timestamp,
										    p_req.oldest_timestamp,
										    p_req.ttl,
										    p_req.version_number,
										    p_req.options,
										    p_req.num_row));
			}

		inline
		std::string get_table_name(const std::string &p_tablet_name)
			{
				// 根据命名规则来取出表名，或建立一个全
				// 局的子表名到表名的映射表来查询
				return naming_strategy::get_table_name_from_tablet_name(p_tablet_name);
			}
		
	private:
	};
} // namespace xbase

#endif	// _XBASE_SERVICE_PROVIDER_HPP_
